package com.googlecode.recycled.lang.jse.api.zip;

import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import com.googlecode.recycled.lang.assertions.Assert;
import com.googlecode.recycled.lang.jse.api.io.FilesExt;
import com.googlecode.recycled.lang.jse.api.io.InputSuppliers;
import org.apache.commons.lang.UnhandledException;

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class Zips {

    public static final String ZIP_ENTRY_PATH_SEPARATOR = "/";

    private Zips() {
    }

    public static void unzip(ZipFile zipFile, File outputDirectory) {
        Enumeration zipEntries = zipFile.entries();
        while (zipEntries.hasMoreElements()) {
            ZipEntry zipEntry = (ZipEntry) zipEntries.nextElement();
            File unzippedFile = new File(outputDirectory, zipEntry.getName());
            if (zipEntry.isDirectory()) {
                FilesExt.assertDirectory(unzippedFile);
            } else {
                try {
                    ByteStreams.copy(InputSuppliers.asInputSupplier(zipFile.getInputStream(zipEntry)), Files.newOutputStreamSupplier(unzippedFile));
                } catch (IOException e) {
                    throw new UnhandledException(e);
                }
            }
        }

    }

    public static String guessRootDirectory(ZipFile zipFile) {
        Assert.notNull(zipFile);

        Enumeration zipEntries = zipFile.entries();
        if (zipEntries.hasMoreElements()) {
            ZipEntry zipEntry = (ZipEntry) zipEntries.nextElement();
            return zipEntry.getName().split(ZIP_ENTRY_PATH_SEPARATOR, 1)[0];
        }
        return null;
    }

    public static String guessRootDirectory(File zipFile) {
        try {
            return guessRootDirectory(new ZipFile(zipFile));
        } catch (IOException e) {
            throw new UnhandledException(e);
        }
    }

}
